package soccerscope.net;

import robocup.component.RobocupAgent;
import soccerscope.SoccerScopeMenuBar;
import soccerscope.model.ClientScene;
import soccerscope.model.Player;
import soccerscope.model.PlayerWorldModel;
import soccerscope.model.Scene;
import soccerscope.model.SimplePlayer;
import soccerscope.model.WorldModel;

/**
 */
public class AgentConnector {

  /**
   * getter for a scene
   * 
   * @param int
   *          the scene number
   * @return the wanted scene
   */
  public static Scene getCycle(int i) {

    return WorldModel.getSceneSet().getScene(i);
  }

  /**
   * returns the number of scenes
   * 
   * @return int
   */
  public static int numberOfCycles() {

    return WorldModel.getSceneSet().size();
  }

  /**
   * Return the WorldModel of the lastScene of one player. If the WorldModel
   * does not exists it will be created.
   * 
   * @param playerNumber
   *          the number of the player
   * @param cycleNumber
   *          the cycle where the world model is searched
   * @return the WorldModel of the player
   */
  private static PlayerWorldModel getPlayerWorldModelOf(int playerNumber,
      int cycleNumber) {

    ClientScene scene = WorldModel.getSceneSet().getSceneOfCycle(cycleNumber);
    if (scene == null) {
      scene = WorldModel.getSceneSet().lastScene();
    }
    Player player = scene.player[playerNumber - 1];
    PlayerWorldModel pwm = player.getWorldModel();
    if (pwm == null) {
      pwm = new PlayerWorldModel();
      player.setWorldModel(pwm);
    }
    return pwm;
  }

  /**
   * Return the WorldModel of the lastScene of one player. If the WorldModel
   * does not exists it will be created.
   * 
   * @param agent
   *          the agent
   * @return the WorldModel of the player
   */
  public static PlayerWorldModel getPlayerWorldModelOf(RobocupAgent agent) {

    if (agent.isTeamEast()) {
      return AgentConnector.getPlayerWorldModelOf(
          agent.getWorld().getNumber() + 11, agent.getWorld().getSelfRef()
              .getCycle());
    }
    else {
      return AgentConnector.getPlayerWorldModelOf(agent.getWorld().getNumber(),
          agent.getWorld().getSelfRef().getCycle());
    }
  }

  /**
   * stores main data to AGame
   * 
   * @param RobocupAgent
   *          the player to add
   * @param SoccerScopeMenuBar
   */
  public static synchronized void addData(RobocupAgent pBean,
      SoccerScopeMenuBar scopeMenu) {

    if (pBean == null) {
      return;
    }

    // Gets the (new) WorldModel of the Player
    PlayerWorldModel pwm = AgentConnector.getPlayerWorldModelOf(pBean);
    double modelCorrection = 1.0;
    if (pBean.isTeamEast()) {
      modelCorrection = -1.0;
    }
    // storing world model data
    if (scopeMenu.storePlayerPosOnOff.getState()) {
      pwm.positionX = pBean.getWorld().getMyPosition().x * modelCorrection;
      pwm.positionY = pBean.getWorld().getMyPosition().y * modelCorrection;
    }
    if (scopeMenu.storePlayerSpeedOnOff.getState()) {
      pwm.speedX = pBean.getWorld().getSelfRef().getSpeed().x * modelCorrection;
      pwm.speedY = pBean.getWorld().getSelfRef().getSpeed().y * modelCorrection;
    }
    if (scopeMenu.storeAnglesOnOff.getState()) {
      pwm.neckAngle = pBean.getWorld().getSelfRef().getNeckAngle();
      pwm.bodyAngle = pBean.getWorld().getBodyAngle();
    }
    if (scopeMenu.storeBallPosOnOff.getState()) {
      pwm.ballPositionX = pBean.getWorld().getBallRef().getPosition().x * modelCorrection;
      pwm.ballPositionY = pBean.getWorld().getBallRef().getPosition().y * modelCorrection;
    }
    if (scopeMenu.storeBallSpeedOnOff.getState()) {
      pwm.ballSpeedX = pBean.getWorld().getBallRef().getSpeed().x * modelCorrection;
      pwm.ballSpeedY = pBean.getWorld().getBallRef().getSpeed().y * modelCorrection;
    }
    if (scopeMenu.storeBallIPOnOff.getState() && pBean.getProphet()
        .getNextBallInterceptionPoint() != null) {
      pwm.ballInterceptX = pBean.getProphet().getNextBallInterceptionPoint().x * modelCorrection;
      pwm.ballInterceptY = pBean.getProphet().getNextBallInterceptionPoint().y * modelCorrection;
    }

    pwm.offsideY = pBean.getWorld().getOffsideY(true) * modelCorrection;

    pwm.PLAY_MODE = "" + pBean.getWorld().getPlayMode();
    
    pwm.based_on_vi = pBean.getWorld().isViBased();
    
    // store opponents and teammates of actual WM
    robocup.component.worldobjects.Player p = null;
    if (scopeMenu.storeTeammatesAndOpponentsOnOff.getState()) {
      for (int i = 0; i < pBean.getWorld().getOpponents().length; i++) {
        // p = pBean.getWorld().getOpponents()[i];
        p = pBean.getWorld().getExpectedPlayers()[i + 11];
        pwm.opponents[i].copy(p, pBean.isTeamEast());
        pwm.opponents[i].ballInterceptionTime = pBean.getProphet()
            .getInterceptionTime(i + 1, false);
        pwm.opponents[i].playerType = p.getPConf().getId();
      }

      for (int i = 0; i < pBean.getWorld().getTeammates().length; i++) {
        p = pBean.getWorld().getExpectedPlayers()[i];

        pwm.teammates[i].copy(p, pBean.isTeamEast());
        pwm.teammates[i].ballInterceptionTime = pBean.getProphet()
            .getInterceptionTime(i + 1, true);
        pwm.teammates[i].stamina = (int) p.getStamina();
        pwm.teammates[i].playerType = p.getPConf().getId();
      }

      // save the next players
      for (int i = 0; i < pBean.getWorld().getNextPlayers().length; i++) {
        p = pBean.getWorld().getNextPlayers()[i];

        if (p.isFriend()) {
          if (p.isMe() || !p.isPredicted()) {
            pwm.nextTeammates[i] = null;
          }
          else {
            pwm.nextTeammates[i] = new SimplePlayer(p, pBean.isTeamEast());
          }
        }
        else {
          if (!p.isPredicted()) {
            pwm.nextOpponents[i - 11] = null;
          }
          else {
            pwm.nextOpponents[i - 11] = new SimplePlayer(p, pBean.isTeamEast());
          }
        }
      }
    }

  }

  /**
   * get a scene with specific cycle number
   * 
   * @param int
   *          cycle
   * @param ClientScene
   *          scene
   */
  static synchronized ClientScene getSceneWithCycleNumber(int cycle) {

    ClientScene scene = new ClientScene();
    for (int i = 0; i < WorldModel.sceneSet.size(); i++) {
      ClientScene tmp = WorldModel.sceneSet.elementAt(i);
      if (tmp == null) {
        return scene;
      }
      if (tmp.time == cycle) {
        return tmp;
      }
    }

    return scene;
  }

  /**
   * store pass data if a player performs a pass
   * 
   * @param RobocupAgent
   *          the player to add
   * @param int
   *          the player number of the destination of the pass
   */
  public static synchronized void addPassData(RobocupAgent shooter,
      int reciever) {

    if (shooter == null) {
      return;
    }

    // Gets the (new) WorldModel of the Player
    PlayerWorldModel pwm = AgentConnector.getPlayerWorldModelOf(shooter);

    // storing world model data
    pwm.doneAPass = true;
    pwm.passToPlayer = reciever;

  }

  /**
   * store hole count
   * 
   * @param RobocupAgent
   *          the player to add
   * @param int
   *          number of holes in actual cycle
   */
  public static synchronized void addHoles(RobocupAgent shooter,
      int numberOfNewHoles) {

    if (shooter == null) {
      return;
    }
    // Gets the (new) WorldModel of the Player
    PlayerWorldModel pwm = AgentConnector.getPlayerWorldModelOf(shooter);

    // storing world model data
    pwm.holes = pwm.holes + numberOfNewHoles;

  }

  /**
   * store state informations/values (new velues such SuccessBenefit or
   * SuccessProb can be added in this method)
   * 
   */
  public static synchronized void addStateAss(RobocupAgent agent,
      String stateInfo) {

    // Gets the (new) WorldModel of the Player
    PlayerWorldModel pwm = AgentConnector.getPlayerWorldModelOf(agent);

    // storing world model data
    pwm.addState(stateInfo);
    // information
  }

}
/**
 * $Log$ Revision 1.2 2006/11/05 13:58:06 wetzker more merging - CLang + MF +
 * some states still missing
 * 
 * Revision 1.1.4.2 2006/10/25 14:33:38 endert Latest SoccerScope Version plus
 * Database ability
 * 
 * Revision 1.1.2.3 2006/08/10 12:42:21 benjaboe Teammates and Opponents can
 * activated for the the AgentWorldModelLayer seperately. BestPosition will be
 * placed by teammates only. (Prophet calculates only these)
 * 
 * Revision 1.1.2.2 2006/08/04 14:00:17 benjaboe PlayerData will be put in the
 * correct cycle not in the last scene
 * 
 * Revision 1.1.2.1 2006/07/31 13:48:59 benjaboe Connection from Agent is named
 * comprehensible
 * 
 * Revision 1.10.4.5 2006/07/31 13:20:08 benjaboe States of the agents is shown
 * on the right side too
 * 
 * Revision 1.10.4.4 2006/07/08 07:40:02 benjaboe Speichern und Laden scheint zu
 * funktionieren
 * 
 * Revision 1.10.4.3 2006/07/02 15:41:37 benjaboe AgentWorldModel is shown for
 * both Team if possible
 * 
 * Revision 1.10.4.2 2006/06/26 14:19:12 benjaboe Player get his own
 * PlayerWorldModel. No NullPointerExceptions when Player has no
 * PlayerWorldModel.
 * 
 * Revision 1.10.4.1 2006/06/26 07:04:23 benjaboe Datamodell umgebaut Revision
 * 1.10 2006/05/17 17:09:55 endert Repaired Layer for MarkOpponent and some new
 * assesments for marking players
 * 
 * Revision 1.9 2006/05/17 14:08:06 endert New Layer for MarkArea
 * 
 * Revision 1.8 2006/05/16 12:01:54 wetzker debugged strange attentionTo and
 * hear behaviour
 * 
 * Revision 1.7 2006/05/05 17:01:02 wetzker best positions are know shown in gui
 * 
 * Revision 1.6 2006/04/18 00:28:01 endert PointTo Ready, OpponentAnalyzer fixed
 * and GUI updated!
 * 
 * Revision 1.5 2006/04/17 12:47:02 endert Point the Stamina, and diplay in
 * AgentWM in SoccerScope
 * 
 * Revision 1.4 2006/04/05 22:48:00 wetzker added prediction of other players
 * state each player now contains a stateEvaluation (see StateTactic) used the
 * prediction for calculation the players of the next cycle (can be seen in the
 * gui) + new State (OpponentBallInterception) for prediction of opponents
 * removed bug in delayed intercetion (cause stamina loss for nothing)
 * meta_playmodes can be used now (added always playmode) improved attack in
 * line
 * 
 * Revision 1.3 2006/03/27 23:25:51 wetzker simplified stateEvaluation - moved
 * most of SimpleState into Abstract - moved most of StateEvaluation into
 * StateTactic adapted GUIUpdate - deleted state tables - only 1 state update
 * each cycle - gui should now be much faster (less holes)
 * 
 * Revision 1.2 2006/03/22 23:38:20 wetzker cleaned gui connection - wm is now
 * only send after an action - added more say + attentionTo logic set dribble
 * state value -20 percent for nightly tournament added state memory to LTM
 * 
 * Revision 1.1 2006/03/13 07:38:37 axle moved from ROOT/src for Maven 2
 * Buildsystem and Team/Soccerscope separation
 * 
 * Revision 1.43 2006/03/07 12:46:37 endert Merge after refactoring: - New
 * State-Interface: One Method for each action type - Action Bean removed -
 * ActionFactorys for helper methods, States calculate main-Action themselves -
 * formatted code - added State-List in Monitor (Context-Menu of Player) - other
 * smaller stuff
 * 
 * Revision 1.42.2.1 2006/03/06 23:17:55 endert Removed warnings, added
 * State-Overview to Context-Menu!
 * 
 * Revision 1.42 2006/02/22 16:05:05 endert This is done: - Rebound SoccerScope
 * to Agents (can be added or removed in config-file) - Situations now all
 * extend abstract class Situation - Refactorings: ActionBean _ removed from
 * Attributes - SoccerScope will automatically connect to host given in
 * Start-Call - Trainer uses the same host as soccerscope - Removed unused stuff
 * (old confs, bat, etc.) - Code formatted (good luck when merging) - organized
 * imports - all that i forgot to mention here Revision 1.41 2006/02/12 14:04:13
 * wetzker debugged AIooB Exc.
 * 
 * Revision 1.40 2006/02/06 17:09:46 endert New Communication merged, bla bla
 * 
 * Revision 1.38.34.1 2005/12/27 19:35:55 endert New Branch created for my Dipl!
 * 
 * Revision 1.38 2005/10/03 11:49:39 andpaul documentation update
 * 
 * Revision 1.37 2005/10/02 17:02:13 andpaul added: state value statistic: per
 * player overview
 * 
 * Revision 1.36 2005/10/01 13:46:16 wetzker organized playersmodel and removed
 * all unsed methods - redifined offside as the y-coordinate of the last
 * opponent but the goalie added predicted interception time to gui added new
 * dashToPoint-version with given time for reaching point added dynamic-depth to
 * pass calculation as it seems very time consuming improved collision with ball
 * model
 * 
 * Revision 1.35 2005/09/27 13:11:34 andpaul updated: state statistic/assessment
 * 
 * Revision 1.34 2005/09/26 22:18:34 andpaul updated: state statistic/values
 * 
 * Revision 1.33 2005/09/07 09:10:40 andpaul removed unused import
 * 
 * Revision 1.32 2005/09/01 17:30:32 thyrion added quick'n'dirty display of
 * opponentinterceptionpoint
 * 
 * Revision 1.31 2005/09/01 10:22:50 wetzker + expectedPlayers[] - by now same
 * as allPlayers except for the player that is fastest to ball - if you got
 * information about players behaviour save it here!! corrected collision bug
 * improved passing and ball interception for near balls some changes for a
 * better performance
 * 
 * Revision 1.30 2005/09/01 08:29:08 andpaul added: showing actual player state
 * in WorldModelLayer (on the right site of the playing field)
 * 
 * Revision 1.29 2005/08/16 16:26:47 wetzker merged composite branch
 * 
 * Revision 1.27.2.3 2005/08/16 15:43:29 wetzker removed ball and player cloning
 * in getSelf, getBall -> should be much faster now merged with changes from
 * head
 * 
 * Revision 1.27.2.2 2005/07/28 11:54:54 wetzker introduced Prophet - by now
 * only used for own ballInterception - changed "Interfaces" - added
 * InterceptOpponent state (very simple Version)
 * 
 * Revision 1.27.2.1 2005/07/15 19:53:46 wetzker added offside line
 * 
 * Revision 1.27 2005/06/26 13:03:28 wetzker renamed getEnemy|FriendlyPlayers to
 * getOpponent & getTeammates refactoring in WM.update
 * 
 * Revision 1.26 2005/06/24 21:29:37 wetzker changes in Agent.WM.Visualization -
 * shadows now got numbers - goalies differ in color
 * 
 * Revision 1.25 2005/06/20 22:19:22 andpaul added: show and save body direction
 * of wm players
 * 
 * Revision 1.24 2005/06/20 21:57:48 andpaul added: store and show reliable flag
 * 
 * Revision 1.23 2005/06/20 17:38:28 andpaul documentation
 * 
 * Revision 1.22 2005/06/20 14:01:46 till changes in getCycle(int i): checking
 * if parameter i is out of range
 * 
 * Revision 1.21 2005/06/15 17:03:32 wetzker removed JIAC from Head + changes in
 * framework please report bugs or shortcomings some scenarios might not work
 * because of wrong imports
 * 
 * Revision 1.17.2.2 2005/06/15 16:44:57 wetzker final version
 * 
 * Revision 1.17.2.1 2005/06/09 12:32:11 endert Removal of JIAC Libraries and
 * dependencies from project, restructuring the framework and improve some
 * aspects (hoping it is an improvement)
 * 
 * Revision 1.20 2005/06/13 16:10:34 andpaul fix: a little bug with the number
 * of cycles when replay
 * 
 * Revision 1.19 2005/06/12 18:52:16 thyrion fixed saving&loading of our
 * worldmodel (to load first open server log)
 * 
 * Revision 1.18 2005/06/06 23:29:41 andpaul added: fields for storring positon
 * average difference and methods to fill them
 * 
 * Revision 1.17 2005/06/05 09:47:09 andpaul added: values to store are
 * selectable via Dai MenuItem
 * 
 * Revision 1.16 2005/05/24 20:07:21 wetzker some refactoring for IP
 * 
 * Revision 1.15 2005/05/22 09:45:29 andpaul changed: using AGame for game
 * representation
 * 
 * Revision 1.14 2005/05/17 21:45:58 andpaul added: support for world model
 * teammates and opponents
 * 
 * Revision 1.13 2005/05/16 15:11:43 haeder changed signature of
 * getInterceptionPoint(), because we always use DAInamiteConstants.WM_V_EFF as
 * speed
 * 
 * Revision 1.12 2005/05/16 14:55:37 haeder removed unused import
 * 
 * Revision 1.11 2005/05/16 12:42:32 wetzker corrected shift - real data was
 * compared with WM-data from last cycle
 * 
 * Revision 1.10 2005/05/15 11:59:51 haeder made the static field cycles
 * thread-safe by making some methods synchronized
 * 
 * Revision 1.9 2005/05/13 22:20:56 wetzker refactoring in LongTermMemory
 * renamed some strange methods gui-statistic is not updated with constant cycle
 * as everything jumps when PM changes turned off some (strange looking)
 * if-cases in GUI-Statistics MeModel now contains viewWidth and viewQuality
 * 
 * Revision 1.8 2005/05/12 17:06:10 wetzker removed bug which leaded to not
 * showing the statistics of number 1 removed yesterdays synchro changes
 * 
 * Revision 1.7 2005/05/09 19:36:43 andpaul removed: debug system.out.println
 * line in addPassData
 * 
 * Revision 1.6 2005/05/09 19:22:40 andpaul added: player pass statistic/charts
 * added: input fileds for maximum values added: holes statistic/charts
 * 
 * Revision 1.5 2005/05/06 16:05:04 andpaul added: two ball possession charts
 * deleted: old stamina chart code in several classes modified: redesign
 * statisticdialog
 * 
 * Revision 1.4 2005/05/02 19:47:26 andpaul added code to fill the ballIntercept
 * attributs in PlayerData
 * 
 * Revision 1.3 2005/05/02 18:26:11 till outsourced FactBase to LongTermMemory
 * 
 * Revision 1.2 2005/04/25 18:45:56 andpaul added: prevent null pointer
 * exception on gui startup in addDate if getVisualInfo is null
 * 
 * Revision 1.1 2005/04/25 14:55:38 andpaul first version of the gui dai-namite
 * player worldmodel history
 * 
 * 
 * 
 */
